package com.cmict.data.bpm.service.listener;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSON;
import com.cmict.data.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
import com.cmict.data.bpm.dal.dataobject.report.ReportUriDO;
import com.cmict.data.bpm.dal.dataobject.task.BpmProcessInstanceExtDO;
import com.cmict.data.bpm.dal.mysql.report.ReportMapper;
import com.cmict.data.bpm.enums.task.BpmProcessInstanceFormStatusEnum;
import com.cmict.data.bpm.service.definition.BpmProcessDefinitionService;
import com.cmict.data.bpm.service.listener.event.ReportEvent;
import com.cmict.data.bpm.service.task.BpmProcessInstanceService;
import com.cmict.data.form.api.task.FormDataApi;
import com.cmict.data.form.api.task.dto.SysFormDTO;
import com.cmict.data.framework.common.pojo.CommonResult;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * /** 数据上报的监听器
 * @author liutao
 * @date 2022/12/14
 */

@Component
public class ReportEventListener implements SmartApplicationListener {

    @Resource
    private BpmProcessInstanceService instanceService;
    @Resource
    private BpmProcessDefinitionService definitionService;
    @Resource
    private ReportMapper reportMapper;
    @Resource
    private FormDataApi formDataApi;

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return eventType == ReportEvent.class;
    }

    @Override
    public boolean supportsSourceType(Class<?> sourceType) {
        return SmartApplicationListener.super.supportsSourceType(sourceType);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        ReportEvent reportEvent = (ReportEvent) event;
        String processDefinitionId = reportEvent.getProcessDefinitionId();
        String instanceId = String.valueOf(reportEvent.getSource());
        List<BpmProcessInstanceExtDO> processInstanceExts = instanceService.getProcessInstanceExts(Collections.singleton(instanceId));
        BpmProcessInstanceExtDO bpmProcessInstanceExtDO = processInstanceExts.get(0);
        Integer formRecordId = bpmProcessInstanceExtDO.getFormRecordId();
        ReportUriDO reportUriDO = new ReportUriDO();
        reportUriDO.setIsReport(0);
        reportUriDO.setId(UUID.randomUUID().toString().replace("-", ""));
        reportUriDO.setQueryParam(JSON.toJSONString(getParamMap(processDefinitionId,formRecordId,bpmProcessInstanceExtDO.getFormStatus())));
        reportMapper.insert(reportUriDO);
    }

    private Map<String, Object> getParamMap(String processDefinitionId,Integer formRecordId,Integer formStatus){
        BpmProcessDefinitionExtDO processDefinitionExt = definitionService.getProcessDefinitionExt(processDefinitionId);
        CommonResult resultData = formDataApi.getDataByIds(formRecordId,processDefinitionExt.getFormId());
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("tableId", processDefinitionExt.getFormId());
        if(resultData.getCode() == 0 && null != resultData.getData()){
            Map<Object,Object> data = (Map<Object, Object>) resultData.getData();
            if(data.containsKey("data_id")){
                paramMap.put("dataId", data.get("data_id"));
                if(BpmProcessInstanceFormStatusEnum.OFFLINE.getStatus() == formStatus){
                    paramMap.put("action","DELETE");
                }else{
                    CommonResult resultTotal = formDataApi.getDataBydataIds((Integer) data.get("data_id"),processDefinitionExt.getFormId());
                    if(resultTotal.getCode() == 0 && null != resultTotal.getData()){
                        Map<Object,Object> dataTotal = (Map<Object, Object>) resultTotal.getData();
                        if(dataTotal.containsKey("total")){
                            paramMap.put("action", (Integer)dataTotal.get("total") == 1 ? "CREATE" : "UPDATE");
                        }
                    }
                }
            }
        }
        return paramMap;
    }
}
